import datetime

from flask_login import UserMixin
from application import db, login_manager


# 用户角色关联表
class UsersRole(db.Model):
    __tablename__ = 'users_role'
    # 用户
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
    # 角色
    role_id = db.Column(db.Integer, db.ForeignKey('role.id'), primary_key=True)


# 角色权限表
class RolePermission(db.Model):
    __tablename__ = 'role_permission'
    # 角色
    role_id = db.Column(db.Integer, db.ForeignKey('role.id'), primary_key=True)
    # 权限
    permission_id = db.Column(db.Integer, db.ForeignKey('permission.id'), primary_key=True)


class Users(UserMixin, db.Model):
    __tablename__ = 'users'
    # 主键
    id = db.Column(db.Integer, primary_key=True)
    # 用户名 唯一索引最长128位
    username = db.Column(db.String(128), unique=True, nullable=False)
    # 密码 必填字段
    password = db.Column(db.String(512), nullable=False)
    # 姓名 创建index索引，加快查询
    fullname = db.Column(db.String(128), index=True, nullable=False)
    # 状态 (1: 生效 0: 禁用)
    status = db.Column(db.SmallInteger, default=1, nullable=False)
    # 当前听课状态
    current_listen_status = db.Column(db.String(32), default='go', nullable=True, index=True)
    # 创建时间 默认当前时间
    created_time = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now, index=True)
    # 用户头像
    avatar = db.Column(db.String(128), nullable=True)
    # 建立指向班级的外键列
    class_id = db.Column(db.Integer, db.ForeignKey('class.id'))
    # 该用户拥有的角色
    roles = db.relationship('UsersRole', foreign_keys=[UsersRole.user_id], backref=db.backref('users', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan')

    def to_json(self):
        if self.uclass:
            json_data = {'id': self.id, 'username': self.username, 'fullname': self.fullname,
                         'created_time': self.created_time, 'classname': self.uclass.name,
                         'current_listen_status': self.current_listen_status,
                         'color': self.get_status()['color']}
        else:
            json_data = {'id': self.id, 'username': self.username, 'fullname': self.fullname,
                         'created_time': self.created_time,
                         'current_listen_status': self.current_listen_status,
                         'color': self.get_status()['color']}
        return json_data

    def get_status(self):
        if self.current_listen_status == 'go':
            return {'color': 'green', 'pic': 'stop'}
        return {'color': 'red', 'pic': 'go'}

    def __repr__(self):
        return self.fullname


# 角色表
class Role(db.Model):
    __tablename__ = 'role'
    # 主键
    id = db.Column(db.Integer, primary_key=True)
    # 角色名
    name = db.Column(db.String(128), unique=True, nullable=False)
    # 角色编码
    code = db.Column(db.String(32), unique=True, nullable=False)
    # 拥有该角色的用户
    users = db.relationship('UsersRole', foreign_keys=[UsersRole.role_id], backref=db.backref('role', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan')
    # 该角色拥有的权限
    permission = db.relationship('RolePermission', foreign_keys=[RolePermission.role_id], backref=db.backref('role', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan')


# 权限表
class Permission(db.Model):
    __tablename__ = 'permission'
    # 主键
    id = db.Column(db.Integer, primary_key=True)
    # 权限名
    name = db.Column(db.String(128), unique=True, nullable=False)
    # 权限编码
    code = db.Column(db.String(32), unique=True, nullable=False)
    # 权限关联的角色
    roles = db.relationship('RolePermission', foreign_keys=[RolePermission.permission_id], backref=db.backref('permission', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan')


# FlaskLogin要求程序实现一个回调函数，使用指定的标识符获取用户
@login_manager.user_loader
def load_user(user_id):
    return Users.query.get(int(user_id))


class Class(db.Model):
    __tablename__ = 'class'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), nullable=False, index=True)
    # 建立学生表引，当relationship中的uselist=False时为一对一关系
    users = db.relationship('Users', backref='uclass')

    def __repr__(self):
        return self.name
